using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Game : MonoBehaviour
{
	public static Game instance;

	[Header("Prefabs")]
	public CharacterInformation playerPrefab;

	public Map[] mapPrefabs;

	public Weapon[] weaponPool;

	[Header("References")]
	[SerializeField]
	private GameSession gameSession;

	public CharacterInformation[] players;

	private Map playingMap;

	public Controller playerController;

	public bool AllowComputer;

	private Coroutine countCoro;

	private Coroutine endgameCoro;

	private Coroutine nextGameCoro;

	private Coroutine worldFreezeCoro;

	private Coroutine spawnWeaponCoro;

	public MenuUI menuUI;

	public IngameUI ingameUI;

	public BackpackUI backpackUI;

	private List<Weapon> weaponCreated;

	private List<Weapon> previousSpawn;

	public Transform[] weaponSpawns;

	public Color[] playerColors;

	public Sprite[] bgSprites;

	public UI2DSprite mapBackground;

	public ShopCoinUI shopcoin;

	public float reDropTime = 18f;

	public float lastTimeShowAds = 15f;

	public bool inGameplay;

	public MenuVisualEffectController visualEffect;

	private float sinceSpawnWeapon;

	private bool allowSpawn;

	public int num = 4;
	private int AlivePlayers
	{
		get
		{
			int num = 0;
			CharacterInformation[] array = players;
			foreach (CharacterInformation characterInformation in array)
			{
				if (characterInformation.isAlive)
				{
					num++;
				}
			}
			return num;
		}
	}

	private void Awake()
	{
		instance = this;
		gameSession = new GameSession();
		players = new CharacterInformation[num];
		weaponCreated = new List<Weapon>();
		previousSpawn = new List<Weapon>();
		shopcoin.ShowCoinTopRight(flag: true);
	}

	private void Start()
	{
		LoadMenu(start: true);
	}

	private void Update()
	{
		if (UnityEngine.Input.GetKeyDown(KeyCode.H))
		{
			for (int i = 1; i < players.Length; i++)
			{
				players[i].GetComponent<CharacterHealth>().TakeDamage(1000f, null, isHeadShot: false);
			}
		}
		if (UnityEngine.Input.GetKeyDown(KeyCode.O))
		{
			SpawnWeapon(UnityEngine.Random.Range(0, weaponPool.Length), playerController.info, Vector3.zero, forcePick: true);
		}
	}

	private void OnDestroy()
	{
		if (players == null)
		{
			return;
		}
		CharacterInformation[] array = players;
		foreach (CharacterInformation characterInformation in array)
		{
			if (characterInformation != null)
			{
				CharacterHealth component = characterInformation.GetComponent<CharacterHealth>();
				component.OnStickmanDie = (Action<CharacterInformation, CharacterInformation>)Delegate.Remove(component.OnStickmanDie, new Action<CharacterInformation, CharacterInformation>(OnStickmanDie));
			}
		}
	}

	public void LoadGameplay()
	{
		visualEffect.Hide();
		menuUI.Hide();
		ingameUI.Show();
		StartNewGame();
	}

	public void LoadMenu(bool start)
	{
		inGameplay = false;
		shopcoin.ShowCoinTopRight(flag: true);
		StopAllCoroutines();
		ClearOlds();
		menuUI.Show();
		ingameUI.Hide();
		visualEffect.Show(start);
	}

	private void ClearOlds()
	{
		CharacterInformation[] array = players;
		foreach (CharacterInformation characterInformation in array)
		{
			if (characterInformation != null && characterInformation.gameObject != null)
			{
				UnityEngine.Object.Destroy(characterInformation.gameObject);
			}
		}
		foreach (Weapon item in weaponCreated)
		{
			if (item != null && item.gameObject != null)
			{
				UnityEngine.Object.Destroy(item.gameObject);
			}
		}
		weaponCreated.Clear();
		if (playingMap != null && playingMap.gameObject != null)
		{
			UnityEngine.Object.Destroy(playingMap.gameObject);
		}
	}

	public void StartNewGame()
	{
		inGameplay = true;
		List<int> list = new List<int>();
		Weapon[] array = weaponPool;
		foreach (Weapon weapon in array)
		{
			if (PersistenData.checkHasItem(weapon.PrefKey))
			{
				list.Add(weapon.id);
			}
		}
		backpackUI.InitBackPack(list);
		playerController.gameObject.SetActive(value: true);
		shopcoin.ShowCoinTopRight(flag: false);
		ClearOlds();
		StopAllCoroutines();
		ingameUI.ShowPreGame();
		players = null;
		players = new CharacterInformation[num];
		SpawnPlayers();
		gameSession.ResetSessionData(mapPrefabs);
		CreateSession();
		for (int i = 0; i < players.Length; i++)
		{
			players[i].tweener.transform.position = playingMap.spawnPosition[i].position;
		}
		ingameUI.ShowPowerUpCount();
		spawnWeaponCoro = StartCoroutine(coroSpawnWeapon(reDropTime));
		allowSpawn = false;
	}

	private void SpawnPlayers()
	{
		foreach (UISprite spr in ingameUI.sprHealthBar)
		{
			spr.transform.parent.gameObject.SetActive(value: false);
		}
		for (int i = 0; i < players.Length; i++)
		{
			players[i] = UnityEngine.Object.Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
			CharacterHealth component = players[i].GetComponent<CharacterHealth>();
			component.OnStickmanDie = (Action<CharacterInformation, CharacterInformation>)Delegate.Combine(component.OnStickmanDie, new Action<CharacterInformation, CharacterInformation>(OnStickmanDie));
			players[i].GetComponent<CharacterHealth>().sprHealthBar = ingameUI.sprHealthBar[i];
			string empty = string.Empty;
			empty = ((i != 0) ? ("敌人 " + (i + 1)) : "你");
			players[i].name = empty;
			ingameUI.lbName[i].text = empty;
			players[i].SetColor(playerColors[i]);
			ingameUI.sprHealthBar[i].transform.parent.gameObject.SetActive(value: true);
			ingameUI.sprHealthBar[i].color = new Color(playerColors[i].r, playerColors[i].g, playerColors[i].b, 1f);
			ingameUI.lbName[i].color = playerColors[i];
		}
		for (int i = 0; i < players.Length; i++)
		{
			SetCharacterLayer(players[i].gameObject, 9 + i);
		}
		playerController.SetControl(players[0], this);
		players[0].GetComponent<AIController>().enabled = false;
		for (int i = 1; i < players.Length; i++)
		{
			players[i].GetComponent<AIController>().enabled = AllowComputer;
			players[i].GetComponent<AIController>().RegisterEnemies(players);
			players[i].GetComponent<CharacterHealth>().SetMaxHealth(300f);
		}
		players[0].GetComponent<CharacterHealth>().damageReduceMultiplier = 0.75f;
		players[0].GetComponent<CharacterHealth>().SetMaxHealth(480f);
	}

	public void SetCharacterLayer(GameObject targetObject, LayerMask layerMask)
	{
		targetObject.layer = layerMask;
		if (targetObject.transform.childCount > 0)
		{
			for (int i = 0; i < targetObject.transform.childCount; i++)
			{
				SetCharacterLayer(targetObject.transform.GetChild(i).gameObject, layerMask);
			}
		}
	}

	public Weapon SpawnWeapon(int weaponID, CharacterInformation holder, Vector3 position, bool forcePick)
	{
		Weapon[] array = weaponPool;
		foreach (Weapon weapon in array)
		{
			if (weapon.id == weaponID)
			{
				Weapon weapon2 = UnityEngine.Object.Instantiate(weapon, position, Quaternion.Euler(0f, 90f, 0f));
				if (holder != null)
				{
					holder.GetComponent<CharacterFighting>().PickupWeapon(weapon2, forcePick);
				}
				else
				{
					weapon2.body.AddTorque(Vector3.right * 1000000f, ForceMode.Acceleration);
				}
				weaponCreated.Add(weapon2);
				return weapon2;
			}
		}
		return null;
	}

	private void CreateSession()
	{
		for (int i = 0; i < players.Length; i++)
		{
			players[i].GetComponent<CharacterHealth>().Respawn();
		}
		for (int i = 1; i < players.Length; i++)
		{
			players[i].GetComponent<AIController>().ResetDelay();
		}

		ingameUI.lbWaveName.text = "Wave: " + (gameSession.sessionCount + 1);
		playerController.HideController();
		SpawnMap(gameSession.currentMapID);
	}

	private void SpawnMap(int mapID)
	{
		if (playingMap != null)
		{
			UnityEngine.Object.Destroy(playingMap.gameObject);
		}
		Map[] array = mapPrefabs;
		foreach (Map map in array)
		{
			if (map.id == gameSession.currentMapID)
			{
				playingMap = UnityEngine.Object.Instantiate(map, Vector3.zero, Quaternion.identity);
				mapBackground.sprite2D = bgSprites[playingMap.backgroundID];
			}
		}
	}

	private IEnumerator coroCount(float waitTime)
	{
		ingameUI.ShowTime("3");
		yield return new WaitForSeconds(waitTime);
		ingameUI.ShowTime("2");
		yield return new WaitForSeconds(waitTime);
		ingameUI.ShowTime("1");
		yield return new WaitForSeconds(waitTime);
		ingameUI.ShowTime("游戏开始!");
		yield return new WaitForSeconds(0.5f);
		AfterCount();
		ingameUI.ShowTime(string.Empty);
	}

	private void AfterCount()
	{
		for (int i = 0; i < players.Length; i++)
		{
			players[i].DeFreeze();
		}
		if (PersistenData.UsingWeapon != -1 && playerController.info.waves == 0)
		{
			SpawnWeapon(PersistenData.UsingWeapon, players[0], Vector3.zero, forcePick: true);
		}
		playerController.ShowController();
		allowSpawn = true;
		sinceSpawnWeapon = 0f;
	}

	private void OnStickmanDie(CharacterInformation caller, CharacterInformation attacker)
	{
		if (caller == playerController.info)
		{
			EndGame();
		}
		else if (AlivePlayers <= 1 && players[0].isAlive)
		{
			if (nextGameCoro != null)
			{
				StopCoroutine(nextGameCoro);
			}
			nextGameCoro = StartCoroutine(coroNextWave());
		}
	}

	private void EndGame()
	{
		if (endgameCoro != null)
		{
			StopCoroutine(endgameCoro);
		}
		endgameCoro = StartCoroutine(coroEndgame());
	}

	private IEnumerator coroEndgame()
	{
		ingameUI.ShowTime("游戏结束", 2f);
		if (spawnWeaponCoro != null)
		{
			StopCoroutine(spawnWeaponCoro);
		}
		Bullet[] array = UnityEngine.Object.FindObjectsOfType<Bullet>();
		foreach (Bullet bullet in array)
		{
			if (bullet != null && bullet.gameObject != null)
			{
				UnityEngine.Object.Destroy(bullet.gameObject);
			}
		}
		playerController.gameObject.SetActive(value: false);
		yield return new WaitForSeconds(2.5f);
		if (Time.time - lastTimeShowAds >= 45f)
		{
			lastTimeShowAds = Time.time;
		}
		ingameUI.ShowTime(string.Empty);
		MyAdManager.Instance.MyShowEndBox();
		ingameUI.ShowPostGame();
		shopcoin.ShowCoinTopRight(flag: true);
		inGameplay = false;
	}

	private IEnumerator coroNextWave()
	{
		ingameUI.ShowTime("干得漂亮!", 2f);
		Time.timeScale = 0.5f;
		Time.fixedDeltaTime = 0.008333334f;
		playerController.info.waves++;
		allowSpawn = false;
		yield return new WaitForSecondsRealtime(4f);
		Time.timeScale = 1f;
		Time.fixedDeltaTime = 0.0166666675f;
		Bullet[] array = UnityEngine.Object.FindObjectsOfType<Bullet>();
		foreach (Bullet bullet in array)
		{
			if (bullet != null && bullet.gameObject != null)
			{
				UnityEngine.Object.Destroy(bullet.gameObject);
			}
		}
		CharacterInformation[] array2 = players;
		foreach (CharacterInformation characterInformation in array2)
		{
			characterInformation.GetComponent<CharacterFighting>().DropWeapon();
			characterInformation.Freeze();
		}
		foreach (Weapon item in weaponCreated)
		{
			if (item != null && item.gameObject != null)
			{
				UnityEngine.Object.Destroy(item.gameObject);
			}
		}
		weaponCreated.Clear();
		ingameUI.ShowTime(string.Empty);
		gameSession.NextSession();
		CreateSession();
		playingMap.tweener.transform.position = new Vector3(0f, 0f, -100f);
		playingMap.tweener.from = playingMap.tweener.transform.localPosition;
		playingMap.tweener.to = Vector3.zero;
		playingMap.tweener.ResetToBeginning();
		playingMap.tweener.PlayForward();
		for (int k = 0; k < players.Length; k++)
		{
			players[k].tweener.from = players[k].tweener.transform.localPosition;
			players[k].tweener.to = playingMap.spawnPosition[k].position - players[k].mainRig.transform.localPosition;
			players[k].tweener.ResetToBeginning();
			players[k].tweener.PlayForward();
		}
		yield return new WaitForSeconds(0.8f);
		List<int> weaponIDs = new List<int>();
		Weapon[] array3 = weaponPool;
		foreach (Weapon weapon in array3)
		{
			if (PersistenData.checkHasItem(weapon.PrefKey))
			{
				weaponIDs.Add(weapon.id);
			}
		}
		backpackUI.InitBackPack(weaponIDs);
		if (countCoro != null)
		{
			StopCoroutine(countCoro);
		}
		countCoro = StartCoroutine(coroCount(0.75f));
	}

	public void TouchToStartGame()
	{
		ingameUI.ShowInplay();
		if (countCoro != null)
		{
			StopCoroutine(countCoro);
		}
		countCoro = StartCoroutine(coroCount(0.75f));
	}

	public void PauseGame()
	{
		MyAdManager.Instance.MyShowNative(0f);
		Time.timeScale = 0f;
		ingameUI.ShowPausePanel();
	}

	public void ResumeGame()
	{
		Time.timeScale = 1f;
		ingameUI.HidePausePanel();
	}

	private IEnumerator coroSpawnWeapon(float delayTime)
	{
		while (true)
		{
			if (sinceSpawnWeapon <= 0f && allowSpawn)
			{
				sinceSpawnWeapon = delayTime;
				foreach (Weapon item2 in previousSpawn)
				{
					if (item2 != null && item2.owner == null)
					{
						UnityEngine.Object.Destroy(item2.gameObject);
						weaponCreated.Remove(item2);
					}
				}
				previousSpawn.Clear();
				Transform[] array = weaponSpawns;
				foreach (Transform transform in array)
				{
					Weapon item = SpawnWeapon(UnityEngine.Random.Range(0, weaponPool.Length), null, transform.position, forcePick: false);
					weaponCreated.Add(item);
					previousSpawn.Add(item);
				}
			}
			sinceSpawnWeapon -= Time.deltaTime;
			yield return new WaitForFixedUpdate();
		}
	}
}
